local Midi = require("midi")

MidiPlaying = {} ---@type table<string, Midi[]>

local MidiTable = {
    ["小城夏天"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("DRUMKIT", "小城夏天", "drumkit"))
        table.insert(examples, Midi.create("ELEC_GUITAR_1", "小城夏天", "guitar"))
        table.insert(examples, Midi.create("GUITAR", "小城夏天", "main_2"))
        table.insert(examples, Midi.create("PIANO", "小城夏天", "main_1"))
        table.insert(examples, Midi.create("ELEC_BASS", "小城夏天", "elec_bass"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["带我去找夜生活"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "带我去找夜生活", "main"))
        table.insert(examples, Midi.create("PIANO", "带我去找夜生活", "acco"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["一点"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "一点", "acco"))
        table.insert(examples, Midi.create("PIANO", "一点", "main"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["世界赠予我的"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "世界赠予我的", "main"))
        table.insert(examples, Midi.create("PIANO", "世界赠予我的", "acco"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["危险派对"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "危险派对", "main"))
        table.insert(examples, Midi.create("PIANO", "危险派对", "acco_high_a"))
        table.insert(examples, Midi.create("PIANO", "危险派对", "acco_low_a"))
        table.insert(examples, Midi.create("PIANO", "危险派对", "acco_low_b"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["无名的人"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "无名的人", "main"))
        table.insert(examples, Midi.create("STANDAR_DRUMKIT", "无名的人", "acco"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["搁浅"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "搁浅", "main"))
        table.insert(examples, Midi.create("PIANO", "搁浅", "acco"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["唯一邓紫棋"] = function(rate, delay)
        local examples = {}
        rate = rate - 0.35
        table.insert(examples, Midi.create("PIANO", "唯一邓紫棋", "main"))
        table.insert(examples, Midi.create("PIANO", "唯一邓紫棋", "acco"))
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["唯一"] = function(rate, delay)
        rate = rate - 0.25
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "唯一王力宏", "main"))
        table.insert(examples, Midi.create("PIANO", "唯一王力宏", "acco"))
        table.insert(examples, Midi.create("DRUMKIT", "唯一王力宏", "drumkit"))
        table.insert(examples, Midi.create("STRING", "唯一王力宏", "string"))
        table.insert(examples, Midi.create("ELEC_BASS", "唯一王力宏", "bass"))
        table.insert(examples, Midi.create("GUITAR", "唯一王力宏", "guitar"))
        examples[4]:set_volume_rate(0.5)
        examples[1]:set_volume_rate(1.5)
        examples[2]:set_volume_rate(0.5)
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["蒲公英的约定"] = function(rate, delay)
        local examples = {}
        rate = rate - 0.5
        table.insert(examples, Midi.create("PIANO", "蒲公英的约定", "main"))
        table.insert(examples, Midi.create("PIANO", "蒲公英的约定", "acco"))
        table.insert(examples, Midi.create("STRING", "蒲公英的约定", "stringA"))
        table.insert(examples, Midi.create("STRING", "蒲公英的约定", "stringB"))
        table.insert(examples, Midi.create("ELEC_BASS", "蒲公英的约定", "elec_bass"))
        table.insert(examples, Midi.create("DRUMKIT", "蒲公英的约定", "drumkit"))
        table.insert(examples, Midi.create("ELEC_GUITAR_1", "蒲公英的约定", "elec_guitar"))
        examples[2]:set_volume_rate(0.25)
        examples[4]:set_volume_rate(0.5)
        examples[5]:set_volume_rate(0.5)
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end,

    ["不为谁而作的歌"] = function(rate, delay)
        local examples = {}
        table.insert(examples, Midi.create("PIANO", "不为谁而作的歌", "main_high"))
        table.insert(examples, Midi.create("PIANO", "不为谁而作的歌", "main_middle"))
        table.insert(examples, Midi.create("PIANO", "不为谁而作的歌", "acco_middle"))
        table.insert(examples, Midi.create("GUITAR", "不为谁而作的歌", "acco_guitar"))
        table.insert(examples, Midi.create("GUITAR", "不为谁而作的歌", "acco_guitar2"))
        table.insert(examples, Midi.create("GUITAR", "不为谁而作的歌", "guitar"))
        table.insert(examples, Midi.create("STRING", "不为谁而作的歌", "string"))
        table.insert(examples, Midi.create("STANDAR_DRUMKIT", "不为谁而作的歌", "drumkit"))
        examples[1]:set_volume_rate(2)
        examples[2]:set_volume_rate(0.5)
        examples[3]:set_volume_rate(0.5)
        for _, example in ipairs(examples) do
            for _, role in ipairs(GameAPI.get_all_valid_roles()) do
                example:set_speed(rate)
                example:add_player(role)
            end
            example:play(delay)
        end
        return examples
    end
}

Methods = {
    play = function(music_name, rate, delay)
        Methods.destroy(music_name)
        if not rate then rate = 1.0 end
        MidiPlaying[music_name] = MidiTable[music_name](rate, delay)
    end,
    pause = function(music_name)
        for _, midi in ipairs(MidiPlaying[music_name]) do
            midi:pause()
        end
    end,
    destroy = function(music_name)
        if not MidiPlaying[music_name] then return end
        for _, midi in ipairs(MidiPlaying[music_name]) do
            midi:destroy()
        end
        MidiPlaying[music_name] = nil
    end,
    resume = function(music_name)
        if not MidiPlaying[music_name] then return end
        for _, midi in ipairs(MidiPlaying[music_name]) do
            midi:resume()
        end
    end
}

return Methods